Occasionally-binding constraints by anticipated shocks ====================================================== The principle ------------- Keep the model's standard (perturbation) solution, but whenever the constraint would be violated, add a sequence of **anticipated shocks** -- "fudge" shocks announced over a horizon :math:`H` -- whose values are chosen so that the constrained variable stays on the admissible side over that horizon. Agents see the announced shocks and react to them, which is what bends the path of the constrained variable; once the constraint is expected to hold of its own accord, no further fudge shocks are needed. This is the approach that underlies modern treatments of the zero lower bound. RISE finds the fudge shocks on a moving window: at each date it solves for the shock values that satisfy the constraint over the next :math:`H` periods (taking into account the shocks it announced earlier), then rolls forward. The shocks can be found by direct inversion or by an optimisation (the routines live in the ``m/+obcas/`` package). The shock horizon ----------------- How far ahead the anticipated shocks may reach is the *shock horizon*. The fudge shock that enforces the constraint is generated automatically for the kink equation and named ``FUDGE_FACTOR_``; set the horizon **on that shock specifically** rather than on every shock in the model:: exo = get(m, 'exo_list'); fudge_name = exo{startsWith(exo, 'FUDGE_FACTOR_')}; m = set(m, 'solve_shock_horizon', {fudge_name, 8}); A bare scalar applies the horizon to *all* shocks:: m = set(m, 'solve_shock_horizon', 8); % every shock anticipated 8 periods which is usually not what you want -- it makes the genuine structural shocks anticipated too, changing the experiment. The constraint is enforced **period by period on a rolling window**, so a short horizon holds the bound across a much longer binding episode: at each date the algorithm fixes the next :math:`H` periods, then rolls forward. You therefore do not need a horizon that spans the whole episode. In practice expectations cease to matter beyond a modest horizon unless the system is hit very hard; an unnecessarily long horizon only enlarges the per-step problem (and can make it harder to solve), so prefer a small :math:`H` (a handful of periods) and increase it only if a deep, persistent episode demands it. Using it -------- Build the constrained model (see :doc:`OCB`), then call ``solve`` and the usual analysis methods -- ``simulate``, ``irf``, ``forecast``, ``filter`` -- which will inject the fudge shocks as needed:: exo = get(m, 'exo_list'); fudge_name = exo{startsWith(exo, 'FUDGE_FACTOR_')}; m = set(m, 'solve_shock_horizon', {fudge_name, 8}); m = solve(m); There are two ways to drive the simulation, and the choice is about *what question you are asking*, not about the constraint machinery. **A controlled scenario.** Prescribe the shocks with a simulation plan and turn shock uncertainty off. The path is deterministic and reproducible -- the canonical "adverse shock, the bound binds, then liftoff" experiment:: sp = simplan(m, [0, 40], 1, 'shockInit', 'zero'); sp = append(sp, 'E_D', 1, -3); % one adverse demand shock sim = simulate(m, 'simul_historical_data', sp, ... 'simul_shock_uncertainty', false); **Random draws.** Let RISE draw the shocks (the default) to study how the model behaves -- for instance how often the bound binds -- under its own shock distribution. Seed the generator for reproducibility:: rng(7); sim = simulate(m, 'simul_periods', 200); Generalized impulse responses are the meaningful ones here, because the response to a shock depends on whether (and how hard) the constraint binds; a simple IRF from a fixed point can misrepresent the dynamics:: gir = irf(m, 'irf_type', 'girf', 'irf_shock_list', {'E_D'}); The constrained step is solved by RISE's OBC solver. The default solver selection works out of the box; for a strongly nonlinear constraint you may set ``simul_optimize`` explicitly to ``'kkt'``, ``'jacobian'`` or ``'fmincon'``. .. tip:: Always ensure there is a feasible path by adjusting potentially-extreme probabilities, e.g. .. math:: p_{ij}=p_{\min }+p_{ij}\left( p_{\max }-p_{\min }\right) Estimation ---------- Models with anticipated-shock constraints can be estimated -- ``filter`` runs the constrained one-step simulator, so the likelihood is consistent with the constraint. For dates at which the constraint is known to bind (or not), see the conditional-forecasting / filtering options that let you flag them and avoid solving an unnecessary inversion. A worked example ---------------- A complete, runnable example -- a small New Keynesian model with a zero lower bound written as the kink ``R = max(0, RSTAR)`` -- ships with the test models at ``models/dsge/obc/worked_examples/anticipated_shocks_zlb/``. Its driver ``howto_zlb_anticipated.m`` solves the model, runs both the controlled-scenario and random-draw simulations described above, and plots the generalized impulse responses. A 3-sigma adverse demand shock holds the policy rate at zero for about four periods before liftoff. .. todo:: Extend the worked example to estimation on artificial data, showing that the likelihood (via the constrained filter) is consistent with the bound.